/**
  ******************************************************************************
  * @file     xmc_ecc.h
  * @version  v2.0.3
  * @date     2021-12-17
  * @brief    header file for the nand ecc configuration.    
  ******************************************************************************
  *                       Copyright notice & Disclaimer
  *
  * The software Board Support Package (BSP) that is made available to 
  * download from Artery official website is the copyrighted work of Artery. 
  * Artery authorizes customers to use, copy, and distribute the BSP 
  * software and its related documentation for the purpose of design and 
  * development in conjunction with Artery microcontrollers. Use of the 
  * software is governed by this copyright notice and the following disclaimer.
  *
  * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
  * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
  * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
  * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
  * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
  *
  **************************************************************************
  */

#ifndef __XMC_NAND_ECC_H
#define __XMC_NAND_ECC_H

#include "stdint.h"
#include "common.h"

/** @addtogroup AT32F437_periph_examples
  * @{
  */

/** @addtogroup 437_XMC_nand_ecc
  * @{
  */
#define K9GAG08U0E

/** @defgroup NAND_id_define
  * @{
  */

typedef union
{
  uint32_t id;
  struct
  {
    uint8_t device_id; /*!< device id */
    uint8_t third_id;  /*!< third id */
    uint8_t fourth_id; /*!< fourth id */
    uint8_t fifth_id;  /*!< fifth id */
    uint8_t sixth_id;  /*!< sixth id */
    uint8_t maker_id;  /*!< maker id */
  };
} nand_id_type;

/**
  * @}
  */

/** @defgroup NAND_address_define
  * @{
  */

typedef struct
{
  uint16_t block; /*!< nand device block address */
  uint16_t page;  /*!< nand device page address */
  uint16_t byte;  /*!< nand device byte address */
} nand_address_type;

/**
  * @}
  */

//NAND属性结构体
typedef struct
{
  u32 id;             //NAND FLASH ID
  u16 page_totalsize; //每页总大小，main区和spare区总和
  u16 page_mainsize;  //每页的main区大小
  u16 page_sparesize; //每页的spare区大小
  u8 block_pagenum;   //每个块包含的页数量
  u16 plane_blocknum; //每个plane包含的块数量
  u16 block_totalnum; //总的块数量
  u8 ecc_err_st;      //ECC 错误状态，无法修复的个数，执行page_read后获取
  u8 ecc_cok_st;      //ECC 修改状态，修复成功的个数，执行page_read后获取
  u32 ecc_hdbuf[8];   //ECC硬件计算值缓冲区
  u32 ecc_rdbuf[8];   //ECC读取的值缓冲区
} nand_attriute;

extern nand_attriute atio_nand;

#define ROW_ADDRESS page
#define COL_ADDRESS coil

#define BUFFER_SIZE NAND_PAGE_SIZE

#define XMC_Bank_NAND XMC_Bank2_NAND
#define Bank_NAND_ADDR Bank2_NAND_ADDR
#define Bank2_NAND_ADDR ((uint32_t)0x70000000)

#ifdef H27U1G8F2CTR_
#define NAND_AT_MakerID 0xAD
#define NAND_AT_DeviceID 0xF1
#elif defined K9GAG08U0E_
#define NAND_AT_MakerID 0xEC
#define NAND_AT_DeviceID 0xD5
#endif

/** @defgroup NAND_area_define
  * @{
  */

/* a16 = cle  high */
#define CMD_AREA (uint32_t)(1 << 16)
/* a17 = ale  high */
#define ADDR_AREA (uint32_t)(1 << 17)

#define DATA_AREA ((uint32_t)0x00000000)

/**
  * @}
  */

/** @defgroup XMC_nand_memory_command
  * @{
  */

/*-- XMC NAND memory command -------------------------------------*/
#define NAND_CMD_AREA_A ((uint8_t)0x00)
#define NAND_CMD_AREA_B ((uint8_t)0x01)
#define NAND_CMD_AREA_C ((uint8_t)0x50)
#define NAND_CMD_AREA_TRUE1 ((uint8_t)0x30)

#define NAND_CMD_WRITE0 ((uint8_t)0x80)
#define NAND_CMD_WRITE_TRUE1 ((uint8_t)0x10)

#define NAND_CMD_ERASE0 ((uint8_t)0x60)
#define NAND_CMD_ERASE1 ((uint8_t)0xD0)

#define NAND_CMD_READID ((uint8_t)0x90)
#define NAND_CMD_STATUS ((uint8_t)0x70)
#define NAND_CMD_LOCK_STATUS ((uint8_t)0x7A)
#define NAND_CMD_RESET ((uint8_t)0xFF)

/**
  * @}
  */

/** @defgroup XMC_nand_status
  * @{
  */

/*-- nand memory status -------------------------------------*/
#define NAND_VALID_ADDRESS ((uint32_t)0x00000100)
#define NAND_INVALID_ADDRESS ((uint32_t)0x00000200)
#define NAND_TIMEOUT_ERROR ((uint32_t)0x00000400)
#define NAND_BUSY ((uint32_t)0x00000000)
#define NAND_ERROR ((uint32_t)0x00000001)
#define NAND_READY ((uint32_t)0x00000040)

/**
  * @}
  */

//NAND FLASH型号和对应的ID号
#define MT29F1G08ABADA 0XF1809502  //MT29F1G08ABADA
#define MT29F4G08ABADA 0XDC909556  //MT29F4G08ABADA
#define MT29F16G08ABABA 0X48002689 //MT29F16G08ABABA

/** @defgroup XMC_nand_parameters
  * @{
  */

/**
  * @}
  */

/** @defgroup XMC_nand_address_computation
  * @{
  */

/*-- xmc nand memory address computation -------------------------------------*/
/* 1st addressing cycle */
#define addr_1st_cycle(addr) (uint8_t)((addr)&0xFF)
/* 2nd addressing cycle */
#define addr_2nd_cycle(addr) (uint8_t)(((addr)&0xFF00) >> 8)
/* 3rd addressing cycle */
#define addr_3rd_cycle(addr) (uint8_t)(((addr)&0xFF0000) >> 16)
/* 4th addressing cycle */
#define addr_4th_cycle(addr) (uint8_t)(((addr)&0xFF000000) >> 24)

/**
  * @}
  */

/** @defgroup XMC_nand_ecc_functions
  * @{
  */

void nand_init(void);
uint32_t nand_read_id(nand_id_type *nand_id_struct);
uint32_t nand_write_page(uint8_t *pbuffer, uint32_t page, uint32_t coil, uint16_t len);
uint32_t nand_read_page(uint8_t *pbuffer, uint32_t page, uint32_t coil, uint16_t len);
uint32_t nand_write_spare_area(uint8_t *pbuffer, uint32_t page, uint32_t coil, uint16_t len);
uint32_t nand_read_spare_area(uint8_t *pbuffer, uint32_t page, uint32_t coil, uint16_t len);
uint32_t nand_erase_block(uint16_t block);
uint32_t nand_reset(void);
uint32_t nand_get_status(void);
uint32_t nand_read_status(void);
uint8_t nand_ecc_correction(uint8_t *pbuffer, uint32_t tx_ecc_value, uint32_t rx_ecc_value);

/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */

#endif
